package com.tsmti.webservice.util;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.tsmti.webservice.constants.Constants;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import javax.xml.bind.JAXBContext;
import javax.xml.bind.Marshaller;
import javax.xml.bind.Unmarshaller;
import java.io.StringReader;
import java.io.StringWriter;
import java.math.BigDecimal;
import java.text.DecimalFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * Title：PimsSystem
 * Class：com.tsmti.core.utils
 * Comapny:
 *
 * @author：zcw
 * @version：2.5 CreateTime：2018/1/16 9:49
 * Modify log:
 * Description：
 */
public final class ConvertUtil {
    private static final Log log = LogFactory.getLog(ConvertUtil.class);
    private static final Pattern NUMBER_PATTERN = Pattern.compile("[0-9]+");
    private static final String DATETYPE_YEAR = "y";
    private static final String DATETYPE_MONTH = "m";
    private static final String DATETYPE_DAY = "d";
    private static final String DATETYPE_HOUR = "h";

    private ConvertUtil() {

    }

    public static String null2String(String s) {
        return s == null ? "" : s;
    }

    public static String null2String(Object s) {
        return s == null ? "" : s.toString();
    }

    public static int getIntValue(Object v) {
        return getIntValue(v, -1);
    }

    public static int getIntValue(Object object, int defval) {
        if (isEmpty(object)) {
            return (defval);
        }
        try {
            return (Integer.parseInt(object.toString()));
        } catch (NumberFormatException e) {
            return (defval);
        }
    }

    public static Long getLongValue(Object v) {
        return getLongValue(v, -1L);
    }

    public static Long getLongValue(Object v, Long def) {
        try {
            return Long.parseLong(null2String(v));
        } catch (Exception ex) {
            return def;
        }
    }

    public static Float getFloatValue(String v) {
        return getFloatValue(v, 0);
    }

    public static Float getFloatValue(String v, float def) {
        try {
            return Float.parseFloat(v);
        } catch (Exception ex) {
            return def;
        }
    }

    public static Double getDoubleValue(String v) {
        return getDoubleValue(v, 0);
    }

    public static Double getDoubleValue(String v, double def) {
        try {
            return Double.parseDouble(v);
        } catch (Exception ex) {
            return def;
        }
    }

    public static double doubleAdd(double v1, double v2) {
        BigDecimal b1 = new BigDecimal(Double.toString(v1));
        BigDecimal b2 = new BigDecimal(Double.toString(v2));
        return b1.add(b2).doubleValue();
    }

    public static double doubleSub(double v1, double v2) {
        BigDecimal b1 = new BigDecimal(Double.toString(v1));
        BigDecimal b2 = new BigDecimal(Double.toString(v2));
        return b1.subtract(b2).doubleValue();
    }

    public static String getFormatDate(Date v) {
        return getFormatDate(v, "");
    }

    public static String getFormatDate(Date v, String format) {
        try {
            if (format == null || format.isEmpty()) {
                format = "yyyy-MM-dd HH:mm:ss";
            }
            SimpleDateFormat simpleDateFormat = new SimpleDateFormat(format);
            return simpleDateFormat.format(v);
        } catch (Exception ex) {
            return "";
        }
    }

    public static String getFormatDateGMT(Date v, String format) {
        try {
            if (v == null){
                v = new Date();
            }
            if (format == null || format.isEmpty()) {
                format = "yyyy-MM-dd HH:mm:ss";
            }
            Calendar calendar = Calendar.getInstance();
            calendar.setTime(v);
            SimpleDateFormat simpleDateFormat = new SimpleDateFormat(format);
            simpleDateFormat.setTimeZone(TimeZone.getTimeZone("GMT"));
            return simpleDateFormat.format(calendar.getTime());
        } catch (Exception ex) {
            return "";
        }
    }


    /**
     * 加千分为
     */
    public static String milfloatFormat(String args) {
        String temp = args;
        String temp1 = "";
        if (!args.isEmpty()) {
            if (args.indexOf(Constants.POINT) == -1) {
                temp = args;
            } else {
                if (!Constants.EMPTY.equals(args.substring(0, args.indexOf(Constants.POINT)))) {
                    temp = args.substring(0, args.indexOf(Constants.POINT));
                } else {
                    temp = "0";
                }
                temp1 = args.substring(args.indexOf(Constants.POINT) + 1);
            }
            double d = getDoubleValue(temp);
            DecimalFormat df = new DecimalFormat("###,###");
            if (args.indexOf(Constants.POINT) == -1) {
                temp1 = "" + df.format(d);
            } else {
                temp1 = "" + df.format(d) + Constants.POINT + temp1;
            }
        }
        return temp1;
    }

    public static List<HashMap<String, Object>> handleJSONArray(JSONArray jsonArray) {
        List list = new ArrayList();
        for (Object object : jsonArray) {
            JSONObject jsonObject = (JSONObject) object;
            HashMap map = new HashMap<String, Object>(16);
            for (Map.Entry entry : jsonObject.entrySet()) {
                if (entry.getValue() instanceof JSONArray) {
                    map.put((String) entry.getKey(), handleJSONArray((JSONArray) entry.getValue()));
                } else {
                    map.put((String) entry.getKey(), entry.getValue());
                }
            }
            list.add(map);
        }
        return list;
    }

    public static String getCompressImagePath(String path) {
        return path.replace("upload", "compress");
    }

    /**
     * 获取当前月第一天
     * @return
     */
    public static String getFirstDayOfMonth() {
        Calendar c = Calendar.getInstance();
        //设置为1号,当前日期既为本月第一天
        c.add(Calendar.MONTH, 0);
        c.set(Calendar.DAY_OF_MONTH, 1);
        return getFormatDate(c.getTime(), "yyyy-MM-dd");
    }

    /**
     * 获取当前月最后一天
     * @return
     */
    public static String getLastDayOfMonth() {
        Calendar ca = Calendar.getInstance();
        ca.set(Calendar.DAY_OF_MONTH, ca.getActualMaximum(Calendar.DAY_OF_MONTH));
        return getFormatDate(ca.getTime(), "yyyy-MM-dd");
    }

    /**
     * 计算两个日期之间相差的天数
     *
     * @param smdate 较小的时间
     * @param bdate  较大的时间
     * @return 相差天数
     * @throws ParseException
     */
    public static Integer daysBetween(Date smdate, Date bdate) throws ParseException {
        try {
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
            smdate = sdf.parse(sdf.format(smdate));
            bdate = sdf.parse(sdf.format(bdate));
            Calendar cal = Calendar.getInstance();
            cal.setTime(smdate);
            long time1 = cal.getTimeInMillis();
            cal.setTime(bdate);
            long time2 = cal.getTimeInMillis();
            long betweenDays= (time2 - time1) / (1000 * 3600 * 24);
            return Integer.parseInt(String.valueOf(betweenDays));
        } catch (Exception e) {
            return null;
        }

    }

    /**
     * 计算两个日期之间相差的分钟
     *
     * @param smdate 较小的时间
     * @param bdate  较大的时间
     * @return 相差天数
     * @throws ParseException
     */
    public static Integer minuteBetween(Date smdate, Date bdate) {
        try {
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            smdate = sdf.parse(sdf.format(smdate));
            bdate = sdf.parse(sdf.format(bdate));
            Calendar cal = Calendar.getInstance();
            cal.setTime(smdate);
            long time1 = cal.getTimeInMillis();
            cal.setTime(bdate);
            long time2 = cal.getTimeInMillis();
            long betweenDays = (time2 - time1) / (1000 * 60);
            return Integer.parseInt(String.valueOf(betweenDays));
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }


    public static Date getString2Date(String strDate) {
        return getString2Date(strDate, "yyyy-MM-dd");
    }

    public static Date getString2Date(String strDate, String format) {
        Date date = null;
        try {
            date = new SimpleDateFormat(format).parse(strDate);
        } catch (Exception e) {
            date = null;
        }
        return date;
    }

    /**
     * @param date  – 日期
     * @param type  – 加减类型 y年m月d日
     * @param value – 加上的数值 如果为负数，则为减去
     * @return 返回增加后的Date
     */
    public static Date dateAdd(Date date, String type, int value) {
        try {
            Calendar cal = Calendar.getInstance();
            cal.setTime(date);
            if (DATETYPE_DAY.equals(type)) {
                //日期加减N天
                cal.add(Calendar.DAY_OF_YEAR, value);
            } else if (DATETYPE_MONTH.equals(type)) {
                //日期加减N个月
                cal.add(Calendar.MONTH, value);
            } else if (DATETYPE_YEAR.equals(type)) {
                //日期加减N年
                cal.add(Calendar.YEAR, value);
            } else if (DATETYPE_HOUR.equals(type)) {
                //日期加减N小时
                cal.add(Calendar.HOUR, value);
            }
            return cal.getTime();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    public static String replaceUTF8Bom(String str) {
        return str.replace("\uFEFF", "");
    }

    public static String toHtml(String s) {
        s = stringReplace(s, "<br>", "" + '\n');
        char[] c = s.toCharArray();
        char ch;
        int i = 0;
        StringBuffer buf = new StringBuffer();

        while (i < c.length) {
            ch = c[i++];
            if (ch == '\'') {
                buf.append("\''");
            }else if (ch == '<') {
                buf.append("&lt;");
            }else if (ch == '>') {
                buf.append("&gt;");
            }else if (ch == '"') {
                buf.append("&quot;");
            }else if (ch == '\n') {
                buf.append("<br>");
            }else {
                buf.append(ch);
            }
        }
        return buf.toString();
    }

    public static String stringReplace(String sou, String s1, String s2) {
        sou = null2String(sou);
        s1 = null2String(s1);
        s2 = null2String(s2);
        try {
            sou = sou.replace(s1, s2);
        } catch (Exception e) {
            System.out.println(e);
        }
        return sou;
    }

    /**
     * 判断字符串是否是数字
     * @param str
     * @return
     */
    public static boolean isNumeric(String str) {
        Matcher isNum = NUMBER_PATTERN.matcher(str);
        if (!isNum.matches()) {
            return false;
        }
        return true;
    }

    public static boolean isEmpty(Object object) {
        if (object == null) {
            return (true);
        }
        if (Constants.EMPTY.equals(object)) {
            return (true);
        }
        if (Constants.NULL.equals(object)) {
            return (true);
        }
        return (false);
    }

    public static boolean isNotEmpty(Object object) {
        if (object != null && ! Constants.EMPTY.equals(object) && ! Constants.NULL.equals(object)) {
            return (true);
        }
        return (false);
    }

    /**
     * JavaBean转换成xml
     * @param obj
     * @param encoding
     * @return
     */
    public static String convertToXml(Object obj, String encoding) {
        String result = null;
        try {
            JAXBContext context = JAXBContext.newInstance(obj.getClass());
            Marshaller marshaller = context.createMarshaller();
            marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
            marshaller.setProperty(Marshaller.JAXB_ENCODING, encoding);

            StringWriter writer = new StringWriter();
            marshaller.marshal(obj, writer);
            result = writer.toString();
        } catch (Exception e) {
            e.printStackTrace();
        }

        return result;
    }

    /**
     * xml转换成JavaBean
     * @param xml
     * @param c
     * @return
     */
    public static <T> T converyToJavaBean(String xml, Class<T> c) {
        T t = null;
        try {
            JAXBContext context = JAXBContext.newInstance(c);
            Unmarshaller unmarshaller = context.createUnmarshaller();
            t = (T) unmarshaller.unmarshal(new StringReader(xml));
        } catch (Exception e) {
            e.printStackTrace();
        }
        return t;
    }
}
